#!/usr/bin/env python2.5

import os,sys
import tempfile, unittest

if sys.platform == 'darwin':
	os.environ['DYLD_LIBRARY_PATH'] = '/opt/local/lib'
	os.environ['DYLD_LIBRARY_PATH'] = '/Users/graph/local/src/rrdtool-1.3.0/src/.libs'

import rrdfile
from rrdfile import RRDLibError

ds1 = "DS:sum:GAUGE:120:U:U"
ds2 = "DS:sumc:COMPUTE:sum,2,*"
rra = "RRA:AVERAGE:0.0:1:5"
up1 = "N:1"

def needs_rrdtool_version(v_wanted):
	""" only available in version X or higher """
	def deco(fn):
		def new(*args):
			if rrdfile.RRDTOOL_VERSION < v_wanted:
				raise RRDLibVersionError("requires rrdtool version %s, %s found" % (v_wanted, v))
			return fn(*args)
		return new
	return deco

class TestrrdfileFunctions(unittest.TestCase):

	def setUp(self):
		tmp = tempfile.mkstemp(suffix='.rrd', prefix='rrdfile_')
		os.close(tmp[0])
		self.rrdfilename = tmp[1]
		#rrdfile.create(self.rrdfilename, rra, ds1, ds2)
		self.dumpfilename = self.rrdfilename + ".xml"
		self.rrdfilename2 = self.rrdfilename + ".2.rrd"
		self.dumpfilename2 = self.rrdfilename + ".2.xml"
		self.rrdgraphfilename = self.rrdfilename + ".png"

	def tearDown(self):
		for f in [self.rrdfilename, self.rrdfilename2, self.dumpfilename, self.dumpfilename2, self.rrdgraphfilename]:
			if os.path.exists(f):
				os.unlink(f)

	def testcreate(self):
		self.failUnlessRaises(RRDLibError, rrdfile.create)
		self.failUnlessRaises(RRDLibError, rrdfile.create, self.rrdfilename)
		self.failUnlessRaises(RRDLibError, rrdfile.create, self.rrdfilename, rra)
		self.failUnlessRaises(RRDLibError, rrdfile.create, self.rrdfilename, ds1)
		self.failIf(rrdfile.create(self.rrdfilename, rra, ds1))
		self.failIf(rrdfile.create(self.rrdfilename, rra, ds1, ds2))

	def testdump(self):
		self.failIf(rrdfile.create(self.rrdfilename, rra, ds1, ds2))
		#self.failIf(rrdfile.dump(self.rrdfilename))
		self.failIf(rrdfile.dump(self.rrdfilename, self.dumpfilename))

	def testfirst(self):
		self.failIf(rrdfile.create(self.rrdfilename, rra, ds1, ds2))
		self.assert_(rrdfile.first(self.rrdfilename))

	def testfetch(self):
		self.failIf(rrdfile.create(self.rrdfilename, rra, ds1, ds2))
		self.assert_(rrdfile.fetch(self.rrdfilename, 'AVERAGE', '-s', '5', '-e', '10'))

	def testgraph(self):
		self.failIf(rrdfile.create(self.rrdfilename, rra, ds1, ds2))
		def1 = "DEF:s=" + self.rrdfilename + ":sum:AVERAGE"
		def2 = "DEF:sc=" + self.rrdfilename + ":sumc:AVERAGE"
		line1 = "LINE1:s#AA00FF:sum\l"

		self.assert_(rrdfile.graph(self.rrdgraphfilename, def1, def2, line1))

	if rrdfile.RRDTOOL_VERSION >= 1.3:
		def testgraph_v(self):
			self.failIf(rrdfile.create(self.rrdfilename, rra, ds1, ds2))
			def1 = "DEF:s=" + self.rrdfilename + ":sum:AVERAGE"
			def2 = "DEF:sc=" + self.rrdfilename + ":sumc:AVERAGE"
			line1 = "LINE1:s#AA00FF:sum\l"
			self.assert_(rrdfile.graph_v(self.rrdgraphfilename, def1, def2, line1))

	def testinfo(self):
		self.failIf(rrdfile.create(self.rrdfilename, rra, ds1, ds2))
		self.assert_(rrdfile.info(self.rrdfilename))

	def testlast(self):
		self.failIf(rrdfile.create(self.rrdfilename, rra, ds1, ds2))
		self.failIf(rrdfile.update(self.rrdfilename, up1))
		self.assert_(rrdfile.last(self.rrdfilename))
		
	def testresize(self):
		self.failIf(rrdfile.create(self.rrdfilename, rra, ds1, ds2))
		self.failIf(rrdfile.resize(self.rrdfilename, 0, "GROW", "2")) # int to str
		self.failIf(rrdfile.resize(self.rrdfilename, "0", "GROW", "2"))

	def testrestore(self):
		self.failIf(rrdfile.create(self.rrdfilename, rra, ds1, ds2))
		self.failIf(rrdfile.dump(self.rrdfilename, self.dumpfilename))
		self.failIf(rrdfile.restore(self.dumpfilename, self.rrdfilename2))
		self.failIf(rrdfile.dump(self.rrdfilename2, self.dumpfilename2))

		self.assertEqual(os.stat(self.dumpfilename)[2], os.stat(self.dumpfilename2)[2])

	def teststrversion(self):
		self.failUnless(rrdfile.strversion())

	def testtune(self):
		self.failIf(rrdfile.create(self.rrdfilename, rra, ds1, ds2))
		self.failIf(rrdfile.tune(self.rrdfilename))

	def testupdate(self):
		self.failIf(rrdfile.create(self.rrdfilename, rra, ds1, ds2))
		self.failIf(rrdfile.update(self.rrdfilename, up1))

	def testversion(self):
		self.failUnless(rrdfile.version())

	def testxport(self):
		self.failIf(rrdfile.create(self.rrdfilename, rra, ds1, ds2))
		def1 = "DEF:s=" + self.rrdfilename + ":sum:AVERAGE"
		xport1 = "XPORT:s"
		self.assert_(rrdfile.xport(def1, xport1))

	def testall(self):
		""" Make sure all rrd library functions are implemented
			/* main function blocks */
			int       rrd_create( int, char **);
			int       rrd_dump( int, char **);
			int       rrd_fetch( int, char **, time_t *, time_t *, unsigned long *, unsigned long *, char ***, rrd_value_t **);
			time_t    rrd_first( int, char **);
			int       rrd_graph( int, char **, char ***, int *, int *, FILE *, double *, double *);
			rrd_info_t rrd_graph_v( int, char **);
			rrd_info_t rrd_info( int, char **);
#			rrd_info_t rrd_info_push( rrd_info_t *, char *, rrd_info_type_t, rrd_infoval_t);
			void      rrd_info_print( rrd_info_t * data);
			void      rrd_info_free( rrd_info_t *);
			time_t    rrd_last( int, char **);
#			int       rrd_lastupdate( int argc, char **argv, time_t *last_update, unsigned long *ds_cnt, char ***ds_namv, char ***last_ds);
			int       rrd_restore( int, char **);
			int       rrd_resize( int, char **);
			char      rrd_strversion( void);
			int       rrd_tune( int, char **);
			int       rrd_update( int, char **);
			rrd_info_t rrd_update_v( int, char **);
			double    rrd_version( void);
			int       rrd_xport( int, char **, int *, time_t *, time_t *, unsigned long *, unsigned long *, char ***, rrd_value_t **);
			int       rrd_create_r( const char *filename, unsigned long pdp_step, time_t last_up, int argc, const char **argv);
			int       rrd_update_r( const char *filename, const char *_template, int argc, const char **argv);
			int       rrd_fetch_r( const char *filename, const char *cf, time_t *start, time_t *end, unsigned long *step, unsigned long *ds_cnt, char ***ds_namv, rrd_value_t **data);
			int       rrd_dump_r( const char *filename, char *outname);
			time_t    rrd_last_r( const char *filename);
			time_t    rrd_first_r( const char *filename, int rraindex);
		"""
		needs_1_3 = ('rrd_info_print', 'rrd_info_free', 'rrd_graph_v')
		for deff in self.testall.__doc__.split("\n")[2:-1]:
			(ret, fn, therest) = deff.split(None, 2)
			fn = fn[:-1]
			if not ret.startswith('#'):
				if not (rrdfile.RRDTOOL_VERSION < 1.3 and fn in needs_1_3):
					self.assert_(hasattr(rrdfile, fn), "%s does not exist" % fn)

	def testtests(self):
		for deff in self.testall.__doc__.split("\n")[2:-1]:
			(ret, fn, therest) = deff.split(None, 2)
			fn = fn[:-1]
			if not ret.startswith('#'):
				testfn = fn.split("_", 2)[1]
				self.assert_(hasattr(self, "test" + testfn), "no test for %s" % fn)

#class TestrrdfileClass(unittest.TestCase):
#	def setUp(self):
#		tmp = tempfile.mkstemp(suffix='.rrd', prefix='rrdfile_')
#		os.close(tmp[0])
#		self.rrdfilename = tmp[1]
#		self.failIf(rrdfile.create(self.rrdfilename, rra, ds1, ds2))
#		self.failIf(rrdfile.update(self.rrdfilename, up1))
#
#	def testopen(self):
#		rrd = rrdfile.open(self.rrdfilename)
#		self.assert_(rrd)
#		print rrd.get_create_cmd()
#
#	def tearDown(self):
#		for f in [self.rrdfilename]:
#			if os.path.exists(f):
#				os.unlink(f)

if __name__ == '__main__':
	unittest.main()

